package com.cfh.springcloudclientapplication.remoteevent;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpRemoteAppEventListener implements SmartApplicationListener {

    private RestTemplate restTemplate = new RestTemplate();

    private DiscoveryClient discoveryClient;

    private String currentAppName;

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return RemoteAppEvent.class.isAssignableFrom(eventType)
                || ContextRefreshedEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof RemoteAppEvent) {
            onApplicationEvent((RemoteAppEvent) event);
        } else if (event instanceof ContextRefreshedEvent) {
            onContextRefreshedEvent((ContextRefreshedEvent) event);
        }
    }

    private void onContextRefreshedEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
        this.currentAppName = applicationContext.getEnvironment().getProperty("spring.application.name");
    }

    private void onApplicationEvent(RemoteAppEvent event) {
        Object source = event.getSource();
        String appName = event.getAppName();
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances(appName);
        if (event.isCluster()) {
            for (ServiceInstance s : serviceInstances) {
                String rooURL = s.isSecure() ?
                        "https://" + s.getHost() + ":" + s.getPort() :
                        "http://" + s.getHost() + ":" + s.getPort();

                String url = rooURL + "/receive/remote/event";
                Map<String, Object> data = new HashMap<>();
                data.put("sender", currentAppName);
                data.put("value", source);
                data.put("type", RemoteAppEvent.class.getName());

                String response = restTemplate.postForObject(url, data, String.class);
                System.out.println(response);
            }
        }
    }
}
